//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<CTreeData.cpp>
///	@path	~/src/database/xdata/
///	@date	2007/11/29
///	@desc	Tree node entry.

#include "config/config.h"

#include "database/xdata/CTreeData.h"

namespace xeres {

	IMPL_IOBJECT_CLASS( CTreeData );

	// ctor
	CTreeData::CTreeData( const WString& name )
		: m_key( Key::MakeKey( name ) )
	{
	}

	// dtor
	CTreeData::~CTreeData( void )
	{
	}

	// GetVarTypeName
	const WString& CTreeData::GetVarTypeName( void ) const
	{
		static const WString s_VoidTypeName( VOID_TYPE_CLASS_NAME );
		return s_VoidTypeName;
	}

	// GetVarTypeID
	const ClassID CTreeData::GetVarTypeID( void ) const
	{
		return VOID_TYPE_CLASS_ID;
	}

	// GetInfo
	bool CTreeData::GetInfo( DataInfo& datainfo )
	{
		datainfo.m_type = DATA_NODE;
		datainfo.m_size = 0;
		datainfo.m_created = 0;
		datainfo.m_accessed = 0;
		datainfo.m_modified = 0;
		return true;
	}

	// GetKey
	const Key& CTreeData::GetKey( void ) const
	{
		return m_key;
	}

	// AddChild
	bool CTreeData::AddChild( RefWeak<IData> child )
	{
		if( child.IsNull() )
		{
			TRACE_ERROR( _S("CTreeData::AddChild: An empty child cannot be added to node.") );
			return false;
		}
		for( size_t i = 0 , total = m_children.size() ; i < total ; ++i )
		{
			if( child == m_children[i] )
			{
				TRACE_ERROR( _S("CTreeData::AddChild: Child node has been added already.") );
				return false;
			}
		}
		m_children.push_back( child );
		return true;
	}

	// OpenData
//	RefPass<IData> CTreeData::OpenData( const WString& path , bool create_non_exist /*= false */ )
//	{
//		return NULL;
//	}

	// IndexOf
	bool CTreeData::IndexOf( RefWeak<IData> child , size_t& index )
	{
		if( child.IsNull() )
			return true;

		for( size_t i = 0 , total = m_children.size() ; i < total ; ++i )
		{
			if( child == m_children[i] )
			{
				index = i;
				return true;
			}
		}
		return false;
	}

	// DeleteChild
	bool CTreeData::DeleteChild( size_t index )
	{
		if( index >= m_children.size() )
		{
			TRACE_ERROR( _S("CTreeData::DeleteChild: Index out of children range.") );
			return false;
		}
		// delete child in tree index
		TRACE_INFO( _S("CTreeData::DeleteChild: Deleting child '%s' from '%s'.") ,
			m_children[index]->GetKey().GetCStr() , m_key.GetCStr() );
		m_children.erase( m_children.begin() + index );

		return false;
	}

	// DeleteChild
	bool CTreeData::DeleteChild( RefWeak<IData> child )
	{
		if( child.IsNull() )
			return true;

		for( size_t i = 0 , total = m_children.size() ; i < total ; ++i )
		{
			if( child == m_children[i] )
			{
				TRACE_INFO( _S("CTreeData::DeleteChild: Deleting child '%s' from '%s'.") , child->GetKey().GetCStr() , m_key.GetCStr() );
				m_children.erase( m_children.begin() + i );
			}
		}
	
		TRACE_ERROR( _S("CTreeData::DeleteChild: Entry '%s' is not in child list of '%s'.") ,
			child->GetKey().GetCStr() , m_key.GetCStr() );
		return false;
	}

	// DeleteChildren
	void CTreeData::DeleteChildren( void )
	{
		m_children.clear();
	}

	// DeleteChildren
	void CTreeData::DeleteChildren( const Key& key )
	{
		for( size_t i = 0 , total = m_children.size() ; i < total ; )
		{
			if( m_children[i]->GetKey() == key )
			{
				m_children.erase( m_children.begin() + i );
			}
			else
			{
				++i;
			}
		}
	}

	// GetChildCount
	size_t CTreeData::GetChildCount( void )
	{
		return m_children.size();
	}

	// GetChild
	RefPass<IData> CTreeData::GetChild( const Key& key )
	{
		for( size_t i = 0 , total = m_children.size() ; i < total ; ++i )
		{
			if( m_children[i]->GetKey() == key )
				return RefPass<IData>( m_children[i] );
		}
		return NULL;
	}

	// GetChild
	RefPass<IData> CTreeData::GetChild( size_t index )
	{
		if( index >= m_children.size() )
		{
			TRACE_ERROR( _S("CTreeData::GetChild: Index out of children range.") );
			return NULL;
		}
		return RefPass<IData>( m_children[index] );
	}

	// GetChildInfo
	bool CTreeData::GetChildInfo( const Key& key , DataInfo& info )
	{
		for( size_t i = 0 , total = m_children.size() ; i < total ; ++i )
		{
			if( m_children[i]->GetKey() == key )
			{
				return m_children[i]->GetInfo( info );
			}
		}
		return false;
	}

	// GetChildInfo
	bool CTreeData::GetChildInfo( size_t index , DataInfo& info , WString& name )
	{
		if( index >= m_children.size() )
		{
			TRACE_ERROR( _S("CTreeData::GetChildInfo: Index out of children range.") );
			return false;
		}
		name = m_children[index]->GetKey().GetCStr();
		return m_children[index]->GetInfo( info );
	}

	// FindChildIndex
	bool CTreeData::FindChildIndex( const Key& key , size_t& index )
	{
		for( size_t total = m_children.size() ; index < total ; ++index )
		{
			if( m_children[index]->GetKey() == key )
				return true;
		}
		index = npos;
		return false;
	}

	// FindChild
	RefPass<IData> CTreeData::FindChild( const Key& key , size_t& index )
	{
		for( size_t total = m_children.size() ; index < total ; ++index )
		{
			if( m_children[index]->GetKey() == key )
			{
				return RefPass<IData>( m_children[index] );
			}
		}
		index = npos;
		return NULL;
	}

	// Save
	bool CTreeData::Save( void )
	{
		for( size_t i = 0 ; i < m_children.size() ; ++i )
		{
			m_children[i]->Save();
		}
		return true;
	}

	// Reload
	bool CTreeData::Reload( void )
	{
		for( size_t i = 0 , total = m_children.size() ; i < total ; ++i )
		{
			m_children[i]->Reload();
		}
		return true;
	}

} // namespace xeres
